package org.vaadinpa.gui.views;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.vaadinpa.Conf;
import org.vaadinpa.data.Planet;
import org.vaadinpa.data.PlanetaryScan;
import org.vaadinpa.data.Resource;
import org.vaadinpa.data.Universe;
import org.vaadinpa.exceptions.NotEnoughFundsException;
import org.vaadinpa.gui.VaadinPA;
import org.vaadinpa.gui.ViewWithCommands;
import org.vaadinpa.gui.util.NotificationUtil;
import org.vaadinpa.logic.Command;
import org.vaadinpa.logic.CommandHandler;
import org.vaadinpa.logic.commands.PlanetaryScanCommand;
import org.vaadinpa.logic.commands.PlanetaryScanCreateCommand;

import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Select;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Reindeer;

@SuppressWarnings("serial")
public class PlanetScanView extends ViewWithCommands {

	private final Label scansLeft = new Label();

	private Button launchScans;

	private final TextField numNewScansField;
	private final Select launchScansField;

	private final Panel oldScans;

	public PlanetScanView() {

		Panel createP = new Panel("Create Scans");
		createP.getContent().setSizeUndefined();
		createP.setSizeUndefined();
		((AbstractOrderedLayout) createP.getContent()).setSpacing(true);
		createP.getContent().addStyleName(Reindeer.LAYOUT_BLACK);

		numNewScansField = new TextField("Create new scans here:");
		createP.addComponent(numNewScansField);
		Button createScans = new Button("Create", new CreateScansListener());
		createP.addComponent(createScans);
		addComponent(createP);

		Panel scanP = new Panel("Launch Scans");
		scanP.getContent().addStyleName(Reindeer.LAYOUT_BLACK);
		scanP.getContent().setSizeUndefined();
		scanP.setSizeUndefined();
		((AbstractOrderedLayout) scanP.getContent()).setSpacing(true);
		addComponent(scanP);

		scansLeft.setWidth("300px");
		scanP.addComponent(scansLeft);
		launchScansField = new Select("Launch here:");
		scanP.addComponent(launchScansField);
		launchScans = new Button("Launch", new LaunchScansListener());
		scanP.addComponent(launchScans);

		oldScans = new Panel("Launched scans:");
		oldScans.getContent().addStyleName(Reindeer.LAYOUT_BLACK);
		oldScans.getContent().setSizeUndefined();
		oldScans.setSizeUndefined();
		((AbstractOrderedLayout) oldScans.getContent()).setSpacing(true);
		addComponent(oldScans);

		setSpacing(true);

		reload();
	}

	@Override
	public void reload() {

		super.reload();

		Planet p = VaadinPA.getPlanet();
		if (p.availablePlanetScans > 0) {
			scansLeft.setValue("You have " + p.availablePlanetScans + " planet scans left");
			launchScans.setEnabled(true);
		} else {
			scansLeft.setValue("You have no planet scans available");
			launchScans.setEnabled(false);
		}

		IndexedContainer cont = new IndexedContainer();
		for (Planet other : Universe.instance.values()) {
			if (p.equals(other)) {
				continue;
			}
			cont.addItem(other);
		}
		launchScansField.setContainerDataSource(cont);
		launchScansField.setNullSelectionAllowed(false);

		oldScans.removeAllComponents();
		List<PlanetaryScan> scans = new ArrayList<PlanetaryScan>(VaadinPA.getPlanet().scans.values());
		Collections.sort(scans);
		for (PlanetaryScan scan : scans) {
			Button showScan = new Button("Scan of " + scan.planet);
			showScan.setData(scan);
			oldScans.addComponent(showScan);
			showScan.addListener(showScanListener);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected List<? extends Command> getCommands() {
		return CommandHandler.getEvents(PlanetaryScanCreateCommand.class, PlanetaryScanCommand.class);
	}

	private class CreateScansListener implements ClickListener {
		public void buttonClick(ClickEvent event) {
			try {

				Planet p = VaadinPA.getPlanet();

				int maxScans = Integer.MAX_VALUE;
				for (Resource r : Resource.valuesWithoutNew()) {
					int maxFromThisResource = p.getFunds(r) / Conf.COST_PLANET_SCAN[r.ordinal()];
					if (maxFromThisResource < maxScans) {
						maxScans = maxFromThisResource;
					}
				}

				int num = new Integer(numNewScansField.getValue().toString()).intValue();
				if (num > maxScans) {
					num = maxScans;
				}
				if (num > 0) {
					PlanetaryScanCreateCommand cmd = new PlanetaryScanCreateCommand(p, num);
					CommandHandler.handle(cmd);
				}
			} catch (NumberFormatException e) {
			} catch (NotEnoughFundsException e) {
				NotificationUtil.warn("", "Not enough resources");
			}
			numNewScansField.setValue(0);

			reload();
		}
	}

	private class LaunchScansListener implements ClickListener {
		public void buttonClick(ClickEvent event) {
			Planet target = (Planet) launchScansField.getValue();

			if (target != null) {
				PlanetaryScanCommand cmd = new PlanetaryScanCommand(VaadinPA.getPlanet(), target);
				CommandHandler.handle(cmd);
			}

			reload();
		}
	}

	@Override
	public String getTitle() {
		return "Planetary scan management";
	}

	private ClickListener showScanListener = new ClickListener() {

		public void buttonClick(ClickEvent event) {

			PlanetaryScan scan = (PlanetaryScan) event.getButton().getData();

			Window w = new Window("Scan of planet " + scan.planet.name);
			w.setModal(true);
			w.setWidth("500px");
			w.setHeight("300px");
			w.center();

			VerticalLayout l = new VerticalLayout();
			l.addStyleName(Reindeer.LAYOUT_BLACK);
			l.setSpacing(true);

			if (scan.techLevelAtScan.ordinal() < VaadinPA.getPlanet().level.ordinal()) {
				Label label = new Label("More comprehensive scanning available!");
				l.addComponent(label);
			}

			Label label = new Label(scan.getNewsReportHTML(), Label.CONTENT_XHTML);
			l.addComponent(label);

			w.setContent(l);

			getWindow().addWindow(w);

		}
	};
}
